package de.fmannan.addbook.editor;

import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.ManagedForm;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.part.EditorPart;

import de.fmannan.addbook.editor.util.StringUtil;

public class GenericEditor extends EditorPart {

	private FormToolkit toolkit;
	private ScrolledForm scrolledForm;
	private ManagedForm managedForm;
	private IGenericEditorInput input;

	public static final String ID = "de.fmannan.addbook.editor.FormView";
	private static Logger log = Logger.getLogger(GenericEditor.class);

	@Override
	public void doSave(IProgressMonitor monitor) {
		managedForm.commit(true);
		setPartName(input.getName());

	}

	@Override
	public void doSaveAs() {
		// we allow do "Save As"
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	/**
	 * True if the ManagedForm is dirty (modified) false otherwise.
	 */
	public boolean isDirty() {
		return managedForm.isDirty();
	}

	@Override
	public void setFocus() {
		scrolledForm.setFocus();
	}

	@Override
	/**
	 * The problem is that, when opening the editor, its init method is not
	 * properly setting the site. The workbench checks that, after init, the
	 * result of getSite() is the same as the site passed to init. Hence we have
	 * to implement the init method of the Editor and check whether the input
	 * has been set correctly.
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException 
	{
		if (!(input instanceof IGenericEditorInput)) {
			log.error("Invalid Input - must be instance of IGenericEditorInput");
		}
		setSite(site);
		setInput(input);
		// Change the name of the editor tab to be the name of the
		// group
		setPartName(input.getName());
		this.input = (IGenericEditorInput) input;
		// Implement copy, cut, paste and delete function
        getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(),
        		new Action(){
		            public void run() {
		            	Control focusControl = Display.getCurrent().getFocusControl();
		            	if (focusControl instanceof Text) {
		            		Text text = (Text)focusControl;
		            		text.cut();
		            	}
		            }
        }); 
        getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(),
        		new Action(){
		            public void run() {
		            	Control focusControl = Display.getCurrent().getFocusControl();
		            	if (focusControl instanceof Text) {
		            		Text text = (Text)focusControl;
		            		text.copy();
		            	}
		            }
        });       
        getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(),
        		new Action(){
		            public void run() {
		            	Control focusControl = Display.getCurrent().getFocusControl();
		            	if (focusControl instanceof Text) {
		            		Text text = (Text)focusControl;
		            		text.paste();
		            	}
		            }
        }); 
        getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(),
        		new Action(){
		            public void run() {
		            	Control focusControl = Display.getCurrent().getFocusControl();
		            	if (focusControl instanceof Text) {
		            		Text text = (Text)focusControl;
		            		text.setText("");
		            	}
		            }
        }); 

        getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
        		new Action(){
		            public void run() {
		            	Control focusControl = Display.getCurrent().getFocusControl();
		            	if (focusControl instanceof Text) {
		            		Text text = (Text)focusControl;
		            		text.selectAll();
		            	}
		            }
        }); 		
	}

	/**
	 * This is a callback that will allow us to create the viewer and
	 * initialize it. The content of a form is created in its body - every
	 * eclipse form has a body.
	 */
	@Override
	public void createPartControl(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());		
		scrolledForm = toolkit.createScrolledForm(parent);
		scrolledForm.setText(StringUtil.toWidget(input.getTitle()));
		scrolledForm.getBody().setLayout(new GridLayout());
		SectionPart sectionPart = new GenericSectionPart(
				scrolledForm.getBody(), toolkit, ExpandableComposite.EXPANDED,
				input);
		managedForm = new ManagedForm(toolkit, scrolledForm);
		managedForm.addPart(sectionPart);
		
		// Thats the most decisive line in that %$§%&§% page of code - it makes
		// the vertical scrollbars appear and it took me hours to figure that
		// out .... try it out - omit it and the scrollbars are gone for good
		managedForm.reflow(true);
	}
	
	public static GridData getGridData(int width, int height) {
		return new GridData(width, height);
	}
}
